package com.zlyx.easy.web.generate.core;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.zlyx.easy.core.tool.EasyBuffer;
import com.zlyx.easy.core.tool.Ops;
import com.zlyx.easy.core.utils.SpringUtils;
import com.zlyx.easy.database.defaults.BaseDao;
import com.zlyx.easy.database.marker.DaoMarker;
import com.zlyx.easy.web.web.controller.AbstractController;
import com.zlyx.easy.web.web.service.AbstractService;
import com.zlyx.easy.web.web.service.impl.AbstractServiceImpl;

/**
 * @Auth 赵光
 * @Describle
 * @2019年1月5日 下午12:59:27
 */
public abstract class AbstractGenerator implements InitializingBean {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	protected boolean isGenerate = true;

	@Autowired
	private DataSourceConfig dataSource;
	
	@Autowired(required = false)
	private DaoMarker daoMarker;

	/*
	 * 全局配置=> 项目相关
	 */
	protected String basePath = System.getProperty("user.dir") + "/src/main/java";

	/*
	 * 局部配置=> 自定义模块设置
	 */
	protected String author = "easy-web 1316851612@qq.com";
	protected String packageName = "easy.web.demo";
	protected String entityName = "Demo";
	protected String tableName = "db_demo";

	private Class<?> abstractDaoClass = BaseDao.class;

	public void run(Map<String, Object> tableBeans) {
		if (tableBeans.containsKey(tableName) || SpringUtils.haveBean(Ops.toUpCase(entityName))) {
			logger.warn(EasyBuffer.wrapper("Generator of ", entityName, " have been created !"));
			return;
		}
		AutoGenerator mpg = new AutoGenerator();
		mpg.setGlobalConfig(getGlobalConfig());
		mpg.setDataSource(dataSource);
		PackageConfig pc = new PackageConfig().setParent(packageName);
		mpg.setPackageInfo(pc);
		mpg.setTemplate(new TemplateConfig().setXml(null));

		// 策略配置
		StrategyConfig strategy = new StrategyConfig();
		strategy.setNaming(NamingStrategy.underline_to_camel);
		strategy.setColumnNaming(NamingStrategy.underline_to_camel);
		strategy.setRestControllerStyle(true);
		strategy.setSuperControllerClass(AbstractController.class.getName());
		strategy.setSuperServiceClass(AbstractService.class.getName());
		strategy.setSuperServiceImplClass(AbstractServiceImpl.class.getName());
		strategy.setSuperMapperClass(abstractDaoClass.getName());
		strategy.setInclude(tableName);
		strategy.setSuperEntityColumns("id");
		strategy.setControllerMappingHyphenStyle(true);
		strategy.setTablePrefix(pc.getModuleName() + "_");
		strategy.entityTableFieldAnnotationEnable(true);
		mpg.setStrategy(strategy);
		mpg.setTemplateEngine(new FreemarkerTemplateEngine());
		mpg.execute();
	}

	public GlobalConfig getGlobalConfig() {
		entityName = Ops.toUpCase(entityName);
		GlobalConfig gc = new GlobalConfig();
		gc.setOutputDir(basePath);
		gc.setAuthor(author);
		gc.setOpen(false);
		gc.setEntityName(entityName);
		gc.setMapperName(entityName + "Mapper");
		gc.setControllerName(entityName + "Controller");
		gc.setServiceName(entityName + "Service");
		gc.setServiceImplName(entityName + "ServiceImpl");
		return gc;
	}

	/**
	 * 关闭代码生成
	 * 
	 * @return
	 */
	public AbstractGenerator close() {
		this.isGenerate = false;
		return this;
	}

	/**
	 * 是否开启代码生成
	 * 
	 * @return
	 */
	public boolean isGenerate() {
		return this.isGenerate;
	}
	
	@Override
	public void afterPropertiesSet() throws Exception {
		if(daoMarker != null) {
			abstractDaoClass = daoMarker.getAbstractDaoClass();
		}
	}
}
